﻿SuperStrict

Framework sedm.bo3d
Import brl.d3d9max2d
Import pub.Win32
Import brl.polledinput
Import brl.random
Import sedm.bullet

Local phys:TBullet = TBullet.Init()

AppTitle = "Ogre3D in a BlitzMax Graphics Window"
Local g:TGraphics = Graphics(800, 600)
Local hwnd:Int = GetForegroundWindow()

EnablePolledInput()

Local r:Root = Root.Create("plugins.cfg")

Local rs:RenderSystem			= r.getRenderSystemByName("Direct3D9 Rendering Subsystem")
r.setRenderSystem(rs)
r.initialise(False)


Local tags:String = ""
tags:+ "externalWindowHandle|" + String(hwnd) + "|"
tags:+ "left|" + String(0) + "|"
tags:+ "top|" + String(0) + "|"
tags:+ "vsync|" + "false"


Local win:RenderWindow = r.createRenderWindow("Ogre3D", GraphicsWidth(), GraphicsHeight(), False, tags)

Local Log:LogManager			= New LogManager

Log.logMessage("let's go!")

Local scene:SceneManager		= r.createSceneManager()
Local res:ResourceGroupManager	= New ResourceGroupManager
Local rsn:SceneNode				= scene.getRootSceneNode()

res.addResourceLocation("media.zip", "Zip", "myFiles")
res.initialiseResourceGroup("myFiles")

Local cam:Camera				= scene.createCamera()
Local vport:Viewport			= win.addViewPort(cam)
Local w:Float = vport.getActualWidth()
Local h:Float = vport.getActualHeight()
cam.setAspectRatio(w / h)
cam.setNearClipDistance(0.1)
	
Local piv:SceneNode				= rsn.createChildSceneNode("player")
piv.attachObject(cam)
piv.SetPosition(0.0, 20.0, 50.0)
vport.setCamera(cam)

scene.SetShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE)
scene.setShadowFarDistance(100.0)
scene.setAmbientLight(ColourValue.Create(0.0, 0.0, 0.0, 0.0))
scene.setSkyBox(True, "SkyBox")

Local l:Light					= scene.CreateLight()
l.setType(LT_POINT)
l.SetPosition(10.0, 100.0, 100.0)
l.setCastShadows(True)

Local box:Entity				= scene.createEntity("", "box.mesh", "myFiles")
Local boxnode:SceneNode			= rsn.createChildSceneNode()
boxnode.attachObject(box)
box.SetPosition(0.0, 100.0, 0.0)
box.setCastShadows(True)


Local ground:Entity				= scene.createEntity("", "ground.mesh", "myFiles")
Local groundnode:SceneNode		= rsn.createChildSceneNode()
groundnode.attachObject(ground)
ground.setCastShadows(False)



' some physics
Local bw:Float = box.getBounds().GetSize().GetX()
Local bh:Float = box.getBounds().GetSize().GetY()
Local bd:Float = box.getBounds().GetSize().GetZ()

Local ground_aab:AxisAlignedBox = ground.getBounds()
Local ground_sze:bVector3 = ground_aab.GetSize()

Local gw:Float = ground_sze.GetX()
Local gh:Float = ground_sze.GetY()
Local gd:Float = ground_sze.GetZ()

Local groundbody:TRigidBody = phys.createRigidBody(CS_BOX, 0.0, False, bVector3.Create(gw, gh, gd))

Local v:Viewport = cam.GetViewport()
Local comp:CompositorManager = r.Compositor_Manager.getSingleton()
Local ci:CompositorInstance = comp.addCompositor(v, "Radial Blur")
comp.setCompositorEnabled(v, "Radial Blur")
Local mat:Material = MaterialManager.getByName("Ogre/Compositor/Radial_Blur")
Local tec:Technique = mat.getTechnique(0)
Local pss:Pass = tec.getPass(0)
Global prs:GpuProgramParameters = pss.getFragmentProgramParameters()

Global sampleDist:Float = 2.0
'prs.setNamedConstant("BlurWeight", sampleDist)
'prs.setNamedConstant("OriginalImageWeight", 1.0)


' Example CompositorInstancelListener
Type myCIListener Extends CIListener
	Field sampleDist:Float
	
	Function notifyMaterialSetup(passId:Int, mat:Material)
		
	End Function
	
	Function notifyMaterialRender(passId:Int, mat:Material)
		prs.setNamedConstant("sampleDist", sampleDist)
		prs.setNamedConstant("sampleStrength", sampleDist)
		DebugLog "notify"
	End Function
End Type
Local cil:myCIListener = New myCIListener
ci.addListener(cil)


Repeat
	Local msx:Int = MouseXSpeed()
	Local msy:Int = MouseYSpeed()
	Local msz:Int = MouseZSpeed()
		
	If KeyDown(KEY_ESCAPE) Then Exit
	If MouseDown(1) Then Exit
	
	If KeyDown(KEY_S) Then piv.translate(0.0, 0.0, 0.5, TS_LOCAL)
	If KeyDown(KEY_W) Then piv.translate(0.0, 0.0, -0.5, TS_LOCAL)
	If KeyDown(KEY_A) Then piv.translate(-0.5, 0.0, 0.0, TS_LOCAL)
	If KeyDown(KEY_D) Then piv.translate(0.5, 0.0, 0.0, TS_LOCAL)
	If KeyHit(KEY_SPACE) Then cloneBox(box, rsn, phys, Rnd(-10.0, 10.0), 50.0, Rnd(-10.0, 10.0))
	
	cil.sampleDist:+ Float(msz) * 0.01
	If cil.sampleDist < 0.0 Then cil.sampleDist = 0.0
	If msz <> 0 Then DebugLog cil.sampleDist
	
	If MouseDown(2)
		cam.pitch(-msy * 0.005)
		piv.yaw(-msx * 0.005, TS_LOCAL)
	End If
	
	Local ft:Float = 1.0 / win.getAverageFPS()
	
	updateDynamics(phys)
	phys.Update()	
	r.renderOneFrame()

Forever

r.Shutdown()

phys = Null	' Important!

End

Type DynEntity Extends Entity
	Global _list:TList
	Field _entity:Entity
	Field _body:TRigidBody
	
	Method New()
		If Self._list = Null Then Self._list = New TList
	End Method
End Type

Function cloneBox(box:Entity, rsn:SceneNode, bullet:TBullet, x:Float, y:Float, z:Float)
	Local e:DynEntity = New DynEntity
	Local box2:Entity				= box.clone()
	Local box2node:SceneNode		= rsn.createChildSceneNode()
	box2node.attachObject(box2)
	box2.SetPosition(x, y, z)
	
	Local bw:Float = box.getBounds().GetSize().GetX()
	Local bh:Float = box.getBounds().GetSize().GetY()
	Local bd:Float = box.getBounds().GetSize().GetZ()
	
	Local boxbody:TRigidBody = bullet.createRigidBody(CS_BOX, 1.0, False, bVector3.Create(bw, bh, bd), bVector3.Create(X, Y, Z))
	
	e._list.AddLast(e)
	e._body = boxbody
	e._entity = box2
End Function


Function updateDynamics(bullet:TBullet)
	If DynEntity._list <> Null
		Local bpos:bVector3
		Local brot:bQuaternion
		
		For Local d:DynEntity = EachIn DynEntity._list
			bpos = bullet.RigidBodyPosition(d._body)
			brot = bullet.RigidBodyRotation(d._body)
				
			d._entity.SetPosition(bpos.getX(), bpos.getY(), bpos.getZ())
			d._entity.SetOrientation(brot)
		Next
	End If
End Function
